package com.alibaba.jvm.sandbox.core.manager.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.jvm.sandbox.api.authentication.JwtTokenService;
import com.alibaba.jvm.sandbox.api.authentication.PayloadDto;
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.UUID;

public class JwtTokenServiceImpl implements JwtTokenService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    public static JwtTokenServiceImpl instance = new JwtTokenServiceImpl();

    // 至少256字符 todo 随机生产256个字符
    private final static String secret = "iblb!Qk&DDHYC3bUsbXdM&UBb1IPn7EL7jb02lPCPcA$B%50q4%8eC!aexvutUCa1y#1^SyuetvB^yh*leLGQF1Ei@q9PV$pR264UQp10CgriMn26Nx^ql@Fo&S$3tD8zlJg^ngu9bxUSkXGlYLe4CsHzUZeqN6UQZKPvjzmP70OOSGsoDCAEn%v^wfnlFo^Yk$c4iepmMaZSKV9REqM*RdYg3d2*aUCeXrEXOq#A1G5Xy8T#NCcm%Ql8CWaPoj%";

    public PayloadDto getDefaultPayloadDto(String username) {
        long iat = System.currentTimeMillis();
        long exp = iat + 5 * 60 * 1000;
        return new PayloadDto(secret, iat, exp, UUID.randomUUID().toString(), username, "ADMIN");
    }

    @Override
    public String generateToken(String payloadStr) {
        JWSObject jwsObject = null;
        try {
            JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.HS256).
                    type(JOSEObjectType.JWT)
                    .build();
            Payload payload = new Payload(payloadStr);
            jwsObject = new JWSObject(jwsHeader, payload);
            JWSSigner jwsSigner = new MACSigner(secret);
            jwsObject.sign(jwsSigner);
        } catch (Exception e) {
            logger.warn("generateToken error", e);
        }
        return jwsObject.serialize();
    }

    @Override
    public boolean verifyToken(String token) {
        JWSObject jwsObject = null;
        JWSVerifier jwsVerifier = null;
        try {
            jwsObject = JWSObject.parse(token);
            jwsVerifier = new MACVerifier(secret);
            if (!jwsObject.verify(jwsVerifier)) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        String payload = jwsObject.getPayload().toString();
        PayloadDto payloadDto = JSONObject.parseObject(payload, PayloadDto.class);
        return payloadDto.getExp() >= new Date().getTime();
    }
}